#ifndef SCREEN_MANAGER_H
#define SCREEN_MANAGER_H

#include <iostream>
#include "Screen.h"
#include "PriorityList.h"

/*
ScreenManager utilizes the PriorityList class to determine draw (and event
and update) order with respect to priority. This allows certain screens to
appear to persist (i.e. always be on top).

This class and priority design means screens that create/open other screens
are less responsible for other screens. They need to:
 1. Create/Open the new screen
 2. Hide itself (note: certain screens may not want to hide entirely, so they
    get control over this.)
[3. Call the new screen's "open" method to ensure it is updatable, eventable,
    and/or drawable. setPriority() could automatically do this, since there
    may never be an instance where we don't want all three enabled when active]

Example use case for screen movement:
 1. User starts at MainMenu
 2. User clicks on start Game
 3. MainMenu hides itself (uneventable, invisible, unupdatable)
 4. MainMenu creates an instance of Game if not already created (eventable, visible, updatable)
 5. User pauses game
 6. Game hides itself (uneventable, invisible, unupdatable)
 7. Game creates MainMenu if not already created (eventable, visible, updatable)
*/
class ScreenManager
{
    // Fields
    private:
        PriorityList screenList;

    // Methods
    public:
        ScreenManager(){};
        virtual ~ScreenManager(){};
        // Sets screen to be drawn on top. Added to screen manager if it doesn't already exist.
        void setPrimary(Screen* screen, int priority = 0)
        {
            // Adding to the priority list may result in the use of a different
            // reference to a screen if the given screen of the same name/type
            // already existes inside the list.
            //std::cout << "before: " << screen << std::endl;
            screenList.add(screen, priority);
            //std::cout << "after: " << screen << std::endl;
            //screen->visible = screen->updatable = screen->eventable = true;
        }
        unsigned int count()
        {
            return screenList.size();
        }
        void printAll()
        {
            screenList.print();
        }
        void drawAll()
        {
            screenList.resetPosition();
            while (screenList.hasNext())
            {
                screenList.getNext()->drawRecursive(false, false);
            }
        }
        void updateAll(Uint32* deltaTime)
        {
            screenList.resetPosition();
            while (screenList.hasNext())
            {
                screenList.getNext()->updateRecursive(deltaTime);
            }
        }
        void handleEventsAll(SDL_Event* event)
        {
            screenList.resetPosition();
            while (screenList.hasNext())
            {
                screenList.getNext()->handleEventsRecursive(event);
            }
        }
};

#endif
